#pragma once
#include "wfx.h"
#include "Scanner.h"
#include "Parser.h"
#include "Production.h"
#include "Scope.h"

#include <vector>


class CGrammar;
class CProduction;

MAKE_PTR(CGrammar);
MAKE_PTR(CProduction)

#ifndef GET_GRAMMAR
#define GET_GRAMMAR() CGrammar::Instance()
#endif


#ifndef REGISTER_SKIP_SPACE_FUNCTION
#define REGISTER_SKIP_SPACE_FUNCTION(func)\
	STATIC_EVAL(GET_GRAMMAR()->GetScannerRule()->RegisterSkipSpaceFunc(func));
#endif

#ifndef REGISTER_NUMBER_SCAN_FUNCTION
#define REGISTER_NUMBER_SCAN_FUNCTION(func)\
	STATIC_EVAL(GET_GRAMMAR()->GetScannerRule()->RegisterNumberScanFunc(func));
#endif

#ifndef REGISTER_WORD_SCAN_FUNCTION
#define REGISTER_WORD_SCAN_FUNCTION(func)\
	STATIC_EVAL(GET_GRAMMAR()->GetScannerRule()->RegisterWordScanFunc(func));
#endif

#ifndef REGISTER_PRODUCTION
#define REGISTER_PRODUCTION(pProdction)\
	STATIC_EVAL(GET_GRAMMAR()->GetParser()->RegisterProduction(pProdction));
#endif

#ifndef PRODUCTION
#define PRODUCTION(production, impl)\
    REGISTER_PRODUCTION(MAKE_PRODUCTION(production,impl));
#endif

class CGrammar
{
public:
    static CGrammarPtr Instance()
    {
        static CGrammarPtr pGramma(new CGrammar());
        return pGramma;
    }

	~CGrammar();

protected:
	CGrammar();
	CGrammar(const CGrammar&);
	CGrammar& operator= (const CGrammar&);
	
private:
	class IMPL;
	IMPL* pImplement;

public:

	CScannerRulePtr GetScannerRule();
	CScannerPtr GetScanner();
	CParserPtr	GetParser();
	
	

    

	void MakeGrammar();


	/************************************************************************/
	/*    interprete Actions                                                */
	/************************************************************************/
public:

	/*
	*	@method interprete
	*	@description interprete
	*	@param std::istream& is the stream of code
	*	@return void
	*/
	void interprete(std::istream& is);

protected:
	/*
	*	@method preInterprete
	*	@description preInterprete
	*	@return void
	*/
	void preInterprete();

	/*
	*	@method postInterprete
	*	@description postInterprete
	*	@return void
	*/
	void postInterprete();

	/************************************************************************/
	/*    Scope Actions                                                     */
	/************************************************************************/
public:

	/*
	*	@method getScope
	*	@description Get the current scope pointer
	*	@return CScopePtr the pointer to the current scope
	*/
	CScopePtr getScope();

	/*
	 *	@method enterScope
	 *	@description Enter a new scope
	 *	@return CScopePtr the pointer to the new scope
	 */
	CScopePtr enterScope();

	/*
	*	@method enterScope
	*	@description Enter a new scope
	*	@param CScopePtr pNewScope the pointer to the new scope
	*	@return CScopePtr the pointer to the new scope
	*/
	CScopePtr enterScope(CScopePtr pNewScope);

	/*
	*	@method leaveScope
	*	@description Leave current scope
	*	@return CScopePtr the pointer to the parent scope
	*/
	CScopePtr leaveScope();

protected:

	
	CScannerRulePtr		m_pScannerRule;
	CScannerPtr			m_pScanner;
	CParserPtr			m_pParser;
	CScopePtr			m_pScope;

};


